Passed
Pull Request — master (#111)
by Kiran
03:52
created

WPInv_Checkout.applyDiscount   A

Complexity

Conditions 2
Paths 5

Size

Total Lines 70

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 5
nop 1
dl 0
loc 70
rs 9.1724
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
// make sure ajaxurl is defined
2
if (typeof ajaxurl === 'undefined' || ajaxurl === null) {
0 ignored issues
show
Bug introduced by
The variable ajaxurl seems to be never declared. If this is a global, consider adding a /** global: ajaxurl */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
3
    // variable is undefined or null
4
    ajaxurl = WPInv.ajax_url;
0 ignored issues
show
Bug introduced by
The variable WPInv seems to be never declared. If this is a global, consider adding a /** global: WPInv */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
Bug introduced by
The variable ajaxurl seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.ajaxurl.
Loading history...
5
}
6
window.wpiSubmit = typeof window.wpiSubmit !== 'undefined' ? window.wpiSubmit : true;
7
jQuery(function($) {
8
    var valid = false;
9
    $('#wpinv_checkout_form').on('submit', function(e) {
10
        var $form = $(this).closest('#wpinv_checkout_form');
11
        $('.wpinv_errors').remove();
12
        if (valid) {
13
            return true;
14
        }
15
        e.preventDefault();
16
        wpinvBlock($form);
17
        var data = $form.serialize();
18
        data = wpinvRemoveQueryVar(data, 'action');
19
        data = wpinvRemoveQueryVar(data, 'wpinv_ajax');
20
        $.post(ajaxurl, data + '&action=wpinv_checkout', function(res) {
0 ignored issues
show
Bug introduced by
The variable ajaxurl does not seem to be initialized in case typeof ajaxurl === "und...ed" || ajaxurl === null on line 2 is false. Are you sure the function post handles undefined variables?
Loading history...
21
            if (res && typeof res == 'object' && res.success) {
22
                valid = true;
23
                var data = new Object();
24
                data.form = $form;
25
                data.totals = res.data;
26
                jQuery('body').trigger('wpinv_checkout_submit', data);
27
                if (window.wpiSubmit) {
28
                    $form.submit();
29
                }
30
            } else {
31
                $form.unblock();
32
                if (res && res.search("wpinv_adddress_confirm") !== -1) {
33
                    $('#wpinv_adddress_confirm').show();
34
                }
35
                $('#wpinv_purchase_submit', $form).before(res);
36
            }
37
        });
38
        return false;
39
    });
40
    var elB = $('#wpinv-fields');
41
    $('#wpinv_country', elB).change(function(e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
42
        $('.wpinv_errors').remove();
43
        wpinvBlock(jQuery('#wpinv_state_box'));
44
        var $this = $(this);
0 ignored issues
show
Unused Code introduced by
The variable $this seems to be never used. Consider removing it.
Loading history...
45
        data = {
0 ignored issues
show
Bug introduced by
The variable data seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.data.
Loading history...
46
            action: 'wpinv_get_states_field',
47
            country: $(this).val(),
48
            field_name: 'wpinv_state',
49
        };
50
        $.post(ajaxurl, data, function(response) {
0 ignored issues
show
Bug introduced by
The variable ajaxurl does not seem to be initialized in case typeof ajaxurl === "und...ed" || ajaxurl === null on line 2 is false. Are you sure the function post handles undefined variables?
Loading history...
51
            if ('nostates' === response) {
52
                var text_field = '<input type="text" required="required" class="wpi-input required" id="wpinv_state" name="wpinv_state">';
53
                $('#wpinv_state', elB).replaceWith(text_field);
54
            } else {
55
                $('#wpinv_state', elB).replaceWith(response);
56
                var changeState = function() {
57
                    console.log('69 : wpinv_recalculate_taxes(' + $(this).val() + ')');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
58
                    wpinv_recalculate_taxes($(this).val());
59
                };
60
                $("#wpinv_state").unbind("change", changeState);
61
                $("#wpinv_state").bind("change", changeState);
62
            }
63
            $('#wpinv_state', elB).find('option[value=""]').remove();
64
            $('#wpinv_state', elB).addClass('form-control wpi-input required');
65
        }).done(function(data) {
0 ignored issues
show
Unused Code introduced by
The parameter data is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
66
            jQuery('#wpinv_state_box').unblock();
67
            console.log('78 : wpinv_recalculate_taxes()');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
68
            wpinv_recalculate_taxes();
69
        });
70
        return false;
71
    });
72
    $('select#wpinv_state', elB).change(function(e) {
0 ignored issues
show
Unused Code introduced by
The parameter e is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
73
        $('.wpinv_errors').remove();
74
        console.log('86 : wpinv_recalculate_taxes()');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
75
        wpinv_recalculate_taxes($(this).val());
76
    });
77
    var WPInv_Checkout = {
78
        checkout_form: $('form#wpinv_checkout_form'),
79
        init: function() {
80
            if (!$(this.checkout_form).length) {
81
                return;
82
            }
83
            // Payment methods
84
            this.checkout_form.on('click', 'input[name="wpi-gateway"]', this.payment_method_selected);
85
            this.init_payment_methods();
86
            //this.recalculate_taxes();
87
        },
88
        init_payment_methods: function() {
89
            var $checkout_form = this.checkout_form;
90
            var $payment_methods = $('.wpi-payment_methods input[name="wpi-gateway"]');
91
            // If there is one method, we can hide the radio input
92
            if (1 === $payment_methods.length) {
93
                $payment_methods.eq(0).hide();
94
            }
95
            // If there are none selected, select the first.
96
            if (0 === $payment_methods.filter(':checked').length) {
97
                $payment_methods.eq(0).prop('checked', true);
98
            }
99
            // Trigger click event for selected method
100
            $payment_methods.filter(':checked').eq(0).trigger('click');
101
            // Validate and apply a discount
102
            $checkout_form.on('click', '#wpi-apply-discount', this.applyDiscount);
103
            // Prevent the checkout form from submitting when hitting enter key in the discount field
104
            $checkout_form.on('keypress', '#wpinv_discount_code', function(event) {
105
                if (event.keyCode == '13') {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if event.keyCode == "13" is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
106
                    return false;
107
                }
108
            });
109
            // Apply the discount when hitting enter key in the discount field instead
110
            $checkout_form.on('keyup', '#wpinv_discount_code', function(event) {
111
                if (event.keyCode == '13') {
112
                    $('#wpi-apply-discount', $checkout_form).trigger('click');
113
                }
114
            });
115
            // Remove a discount
116
            $(document.body).on('click', '.wpi-discount-remove', this.removeDiscount);
117
        },
118
        payment_method_selected: function() {
119
            if ($('.wpi-payment_methods input.wpi-pmethod').length > 1) {
120
                var target_payment_box = $('div.payment_box.' + $(this).attr('ID'));
121
                if ($(this).is(':checked') && !target_payment_box.is(':visible')) {
122
                    $('div.payment_box').filter(':visible').slideUp(250);
123
                    if ($(this).is(':checked')) {
124
                        var content = $('div.payment_box.' + $(this).attr('ID')).html();
125
                        content = content ? content.trim() : '';
126
                        if (content) {
127
                            $('div.payment_box.' + $(this).attr('ID')).slideDown(250);
128
                        }
129
                    }
130
                }
131
            } else {
132
                $('div.payment_box').show();
133
            }
134
            $('#wpinv_payment_mode_select').attr('data-gateway', $(this).val());
135
            wpinvSetPaymentBtnText($(this), $('#wpinv_payment_mode_select').data('free'));
136
        },
137
        applyDiscount: function(e) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
138
            e.preventDefault();
139
            var $this = $(this),
140
                $box = $this.closest('.panel-body'),
141
                discount_code = $('#wpinv_discount_code', $box).val(),
142
                $msg = $('.wpinv-discount-msg', $box),
143
                $msgS = $('.alert-success', $msg),
144
                $msgF = $('.alert-error', $msg);
145
            if (discount_code == '') {
146
                $('#wpinv_discount_code', $box).focus();
147
                return false;
148
            }
149
            var data = {
150
                action: 'wpinv_apply_discount',
151
                code: discount_code,
152
                _nonce: WPInv.nonce
0 ignored issues
show
Bug introduced by
The variable WPInv seems to be never declared. If this is a global, consider adding a /** global: WPInv */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
153
            };
154
            $('.wpinv_errors').remove();
155
            $msg.hide();
156
            $msgS.hide().find('.wpi-msg').html('');
157
            $msgF.hide().find('.wpi-msg').html('');
158
            wpinvBlock($box);
159
            $.ajax({
160
                type: "POST",
161
                data: data,
162
                dataType: "json",
163
                url: WPInv.ajax_url,
164
                xhrFields: {
165
                    withCredentials: true
166
                },
167
                success: function(res) {
168
                    wpinvUnblock($box);
169
                    var success = false;
170
                    if (res && typeof res == 'object') {
171
                        if (res.success) {
172
                            success = true;
173
                            jQuery('#wpinv_checkout_cart_form', $this.checkout_form).replaceWith(res.data.html);
174
                            jQuery('.wpinv-chdeckout-total').text(res.data.total);
175
                            $('#wpinv_discount_code', $box).val('');
176
                            //console.log('217 : wpinv_recalculate_taxes()');
177
                            //wpinv_recalculate_taxes();
178
                            if (res.data.free) {
179
                                $('#wpinv_payment_mode_select', $this.checkout_form).hide();
180
                                gw = 'manual';
0 ignored issues
show
Bug introduced by
The variable gw seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.gw.
Loading history...
181
                            } else {
182
                                $('#wpinv_payment_mode_select', $this.checkout_form).show();
183
                                gw = $('#wpinv_payment_mode_select', $this.checkout_form).attr('data-gateway');
184
                            }
185
                            $('.wpi-payment_methods .wpi-pmethod[value="' + gw + '"]', $this.checkout_form).prop('checked', true);
186
                            wpinvSetPaymentBtnText($('.wpi-payment_methods .wpi-pmethod[value="' + gw + '"]', $this.checkout_form), res.data.free);
187
                            $(document.body).trigger('wpinv_discount_applied', [res]);
188
                        }
189
                        if (res.msg) {
190
                            $msg.show();
191
                            if (success) {
192
                                $msgS.show().find('.wpi-msg').html(res.msg);
193
                            } else {
194
                                $msgF.show().find('.wpi-msg').html(res.msg);
195
                            }
196
                        }
197
                    }
198
                }
199
            }).fail(function(res) {
200
                wpinvUnblock($box);
201
                if (window.console && window.console.log) {
202
                    console.log(res);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
203
                }
204
            });
205
            return false;
206
        },
207
        removeDiscount: function(e) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
208
            e.preventDefault();
209
            var $this = $(this),
210
                $block = $this.closest('#wpinv_checkout_cart_wrap'),
211
                discount_code = $this.data('code');
212
            if (discount_code == '') {
213
                return false;
214
            }
215
            var data = {
216
                action: 'wpinv_remove_discount',
217
                code: discount_code,
218
                _nonce: WPInv.nonce
0 ignored issues
show
Bug introduced by
The variable WPInv seems to be never declared. If this is a global, consider adding a /** global: WPInv */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
219
            };
220
            wpinvBlock($block);
221
            $.ajax({
222
                type: "POST",
223
                data: data,
224
                dataType: "json",
225
                url: WPInv.ajax_url,
226
                xhrFields: {
227
                    withCredentials: true
228
                },
229
                success: function(res) {
230
                    if (res && typeof res == 'object') {
231
                        if (res.success) {
232
                            jQuery('#wpinv_checkout_cart_form', $this.checkout_form).replaceWith(res.data.html);
233
                            jQuery('.wpinv-chdeckout-total').text(res.data.total);
234
                            if (res.data.free) {
235
                                $('#wpinv_payment_mode_select', $this.checkout_form).hide();
236
                                gw = 'manual';
0 ignored issues
show
Bug introduced by
The variable gw seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.gw.
Loading history...
237
                            } else {
238
                                $('#wpinv_payment_mode_select', $this.checkout_form).show();
239
                                gw = $('#wpinv_payment_mode_select', $this.checkout_form).attr('data-gateway');
240
                            }
241
                            $('input[name="wpi-gateway"][value="' + gw + '"]', $this.checkout_form).prop('checked', true);
242
                            wpinvSetPaymentBtnText($('input[name="wpi-gateway"][value="' + gw + '"]', $this.checkout_form), res.data.free);
243
                            //console.log('291 : wpinv_recalculate_taxes()');
244
                            //wpinv_recalculate_taxes();
245
                            $(document.body).trigger('wpinv_discount_removed', [res]);
246
                        }
247
                    }
248
                }
249
            }).fail(function(res) {
250
                wpinvUnblock($block);
251
                if (window.console && window.console.log) {
252
                    console.log(res);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
253
                }
254
            });
255
            return false;
256
        },
257
        recalculate_taxes: function() {
258
            console.log('308 : wpinv_recalculate_taxes()');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
259
            wpinv_recalculate_taxes();
260
        }
261
    }
262
    WPInv_Checkout.init();
263
});
264
265
function wpinvBlock(el, message) {
266
    message = typeof message != 'undefined' && message !== '' ? '&nbsp;' + message : '';
267
    el.block({
268
        message: '<i class="fa fa-refresh fa-spin"></i>' + message,
269
        overlayCSS: {
270
            background: '#fff',
271
            opacity: 0.6
272
        },
273
        ignoreIfBlocked: true
274
    });
275
}
276
277
function wpinvSetPaymentBtnText(el, free) {
278
    var btnTxt = jQuery(el).data('button-text') ? jQuery(el).data('button-text') : jQuery('#wpinv-payment-button').data('value');
279
    if (free) {
280
        btnTxt = WPInv.txtComplete;
0 ignored issues
show
Bug introduced by
The variable WPInv seems to be never declared. If this is a global, consider adding a /** global: WPInv */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
281
    }
282
    
283
    jQuery('form#wpinv_checkout_form #wpinv-payment-button').val(btnTxt);
284
}
285
286
function wpinvUnblock(el) {
287
    el.unblock();
288
}
289
290
function wpinvRemoveQueryVar(url, parameter) {
291
    //prefer to use l.search if you have a location/link object
292
    var urlparts = url.split('?');
293
    var urlparts2 = url.split('&');
294
    if (urlparts.length >= 2) {
295
        var prefix = encodeURIComponent(parameter) + '=';
296
        var pars = urlparts[1].split(/[&;]/g);
297
        //reverse iteration as may be destructive
298
        for (var i = pars.length; i-- > 0;) {
299
            //idiom for string.startsWith
300
            if (pars[i].lastIndexOf(prefix, 0) !== -1) {
301
                pars.splice(i, 1);
302
            }
303
        }
304
        url = urlparts[0] + (pars.length > 0 ? '?' + pars.join('&') : "");
305
        return url;
306
    } else if (urlparts2.length >= 2) {
307
        var prefix = encodeURIComponent(parameter) + '=';
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable prefix already seems to be declared on line 295. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
308
        var pars = url.split(/[&;]/g);
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable pars already seems to be declared on line 296. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
309
        //reverse iteration as may be destructive
310
        for (var i = pars.length; i-- > 0;) {
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable i already seems to be declared on line 298. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
311
            //idiom for string.startsWith
312
            if (pars[i].lastIndexOf(prefix, 0) !== -1) {
313
                pars.splice(i, 1);
314
            }
315
        }
316
        url = pars.join('&');
317
        return url;
318
    } else {
319
        return url;
320
    }
321
}
322
323
/**
324
 * Allow a invoice to be created for items via ajax.
325
 * @param items This is a comma separated and pipe separated for quantity eg:  item_id|quantity,item_id|quantity,item_id|quantity
326
 */
327
function wpi_buy(items,$post_id){
328
    var $nonce = jQuery('#wpinv_buy_nonce').val();
329
    jQuery.ajax({
330
        url : ajaxurl,
0 ignored issues
show
Bug introduced by
The variable ajaxurl does not seem to be initialized in case typeof ajaxurl === "und...ed" || ajaxurl === null on line 2 is false. Are you sure this can never be the case?
Loading history...
331
        type : 'post',
332
        data : {
333
            action : 'wpinv_buy_items',
334
            items : items,
335
            post_id : $post_id,
336
            wpinv_buy_nonce : $nonce
337
        },
338
        success : function( res ) {
339
            console.log(res);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
340
            if (typeof res == 'object' && res) {
341
                if (res.success) {
342
                    window.location.href = res.success;
343
                    return;
344
                }
345
                if (res.error) {
346
                    alert(res.error);
347
                }
348
            }
349
        }
350
    });
351
}